package net.jescort.lucene.runnable;

import net.jescort.domain.forum.Post;
import net.jescort.lucene.FieldConstants;
import net.jescort.lucene.impl.IndexManagerImpl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.util.Version;

import java.io.IOException;

/**
 * Created by IntelliJ IDEA.
 * User: admin@gelif.net
 * Date: 11-8-25
 * Time: 下午3:46
 */
public abstract class IndexRunnable implements Runnable
{
    private static Log logger = LogFactory.getFactory().getInstance(IndexRunnable.class);

    //~ Instance fields
    // ========================================================
    protected IndexManagerImpl manager;
    private IndexReader reader;
    private IndexWriter writer;

    //~ Constructors
    // ===========================================================
    public IndexRunnable(IndexManagerImpl manager)
    {
        this.manager = manager;
    }

    //~ Methods
    // ================================================================
    protected Document getDocument(Post data)
    {
        Document doc = new Document();

        // keyword
        doc.add(new Field(FieldConstants.ID, data.getId(),
                Field.Store.YES, Field.Index.NOT_ANALYZED));

        // keyword
        doc.add(new Field(FieldConstants.WEBSITE_HANDLE,
                data.getWebsite().getHandle(),
                Field.Store.YES, Field.Index.NOT_ANALYZED));

        // unindexed
        doc.add(new Field(FieldConstants.ANCHOR,
                data.getAnchor(),
                Field.Store.YES, Field.Index.NO));

        // text
        doc.add(new Field(FieldConstants.USERNAME,
                data.getCreator().getUserName(),
                Field.Store.YES, Field.Index.ANALYZED));

        // text
        doc.add(new Field(FieldConstants.TITLE, data.getTitle(), Field.Store.YES, Field.Index.ANALYZED));

        // index the entry text, but don't store it - moved to end of block
        // unstored
        doc.add(new Field(FieldConstants.CONTENT,
                data.getText(),
                Field.Store.NO, Field.Index.ANALYZED));

        // store an abbreviated version of the entry text, but don't index
        // unindexed
        doc.add(new Field(FieldConstants.CONTENT_STORED,
                Utilities.truncateNicely(Utilities.removeHTML(data.getText()), 240, 260, "..."),
                Field.Store.YES, Field.Index.NO));

        // keyword
        doc.add(new Field(FieldConstants.UPDATED,
                data.getUpdateTime().toString(),
                Field.Store.YES, Field.Index.NOT_ANALYZED));

        // keyword
        doc.add(new Field(FieldConstants.PUBLISHED,
                data.getPubTime().toString(),
                Field.Store.YES, Field.Index.NOT_ANALYZED));

        // index Comments
        // unstored
        doc.add(new Field(FieldConstants.C_CONTENT,
                commentContent,
                Field.Store.NO, Field.Index.ANALYZED));
        // unstored
        doc.add(new Field(FieldConstants.C_EMAIL,
                commentEmail,
                Field.Store.NO, Field.Index.ANALYZED));
        // unstored
        doc.add(new Field(FieldConstants.C_NAME,
                commentName,
                Field.Store.NO, Field.Index.ANALYZED));

        // unstored
        doc.add(new Field(FieldConstants.CONSTANT,
                FieldConstants.CONSTANT_V,
                Field.Store.NO, Field.Index.ANALYZED));

        return doc;
    }

    protected IndexReader beginDeleting()
    {
        try
        {
            reader = IndexReader.open(manager.getIndexDirectory());
        } catch (IOException e)
        {
        }

        return reader;
    }

    protected void endDeleting()
    {
        if (reader != null)
        {
            try
            {
                reader.close();
            } catch (IOException e)
            {
                logger.error("ERROR closing reader");
            }
        }
    }

    protected IndexWriter beginWriting()
    {
        try
        {
            writer = new IndexWriter(manager.getIndexDirectory(), new IndexWriterConfig(Version.LUCENE_33, IndexManagerImpl.getAnalyzer()).setOpenMode(IndexWriterConfig.OpenMode.CREATE_OR_APPEND));
        } catch (IOException e)
        {
            logger.error("ERROR creating writer", e);
        }

        return writer;
    }

    protected void endWriting()
    {
        if (writer != null)
        {
            try
            {
                writer.close();
            } catch (IOException e)
            {
                logger.error("ERROR closing writer", e);
            }
        }
    }

    public void run()
    {
        doRun();
    }

    protected abstract void doRun();
}
